package li.brauch.semesterarbeit.radio.views.widgets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

public class VolumeSlider extends Canvas {
	
	private Color rollover = Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION);
	
	private int value = 0;
	private int minimum = 0;
	private int maximum = 100;
	
	private boolean mouseDown = false;
	private int mouseX = 0;
	private boolean mouseEnter = false;
	
	public VolumeSlider(Composite parent, int style) {
		super(parent, style);
		
		addPaintListener(new PaintListener() {
	         public void paintControl(PaintEvent e) {
	        	 VolumeSlider.this.paintControl(e);
	         }
	     });
		
		addListener(SWT.MouseEnter, new Listener() {			
			public void handleEvent(Event event) {
				mouseEnter = true;
				redraw();
			}
		});
		
		addListener(SWT.MouseExit, new Listener() {			
			public void handleEvent(Event event) {
				mouseEnter = false;
				redraw();
			}
		});
		
		addMouseListener(new MouseAdapter() {	
			
			public void mouseDown(MouseEvent e) {
				Point point = getSize();
				mouseX = Math.min(e.x, point.x);
				value = Math.max(0, Math.round((maximum - minimum) * mouseX / point.x));
				redraw();
				mouseDown = true;				
			}
			
			public void mouseUp(MouseEvent e) {
				mouseDown = false;
				
				Point point = getSize();
				value = Math.max(0, Math.round((maximum - minimum) * mouseX / point.x));
				
				Event event = new Event();
				event.item = VolumeSlider.this;				
				event.data = new Integer(value);
				notifyListeners(SWT.Selection, event);
			}
		});
		
		addMouseMoveListener(new MouseMoveListener() {
			
			public void mouseMove(MouseEvent e) {
				if (mouseDown) {
					Point point = getSize();
					mouseX = Math.min(e.x, point.x);
					value = Math.max(0, Math.round((maximum - minimum) * mouseX / point.x));
					
					Event event = new Event();
					event.item = VolumeSlider.this;				
					event.data = new Integer(value);
					notifyListeners(SWT.Selection, event);
					
					redraw();
				}
			}
		});
	}
	
	void paintControl(PaintEvent e) {

	     GC gc = e.gc;
	     
	     int width = e.width;
	     int height = e.height;
	     
	     Color oldColor = gc.getForeground();
	     
	     Rectangle rectangle = new Rectangle(0, 0, width, height);
	     gc.fillRectangle(rectangle);
	     	     
	     if (mouseEnter) {
	    	 gc.setForeground(rollover);	    	 
	     }
	     
	     rectangle = new Rectangle(0, 0, width - 1, height - 1);	     
	     gc.drawRectangle(rectangle);	     
	     
	     if (mouseEnter) {
	    	 gc.setForeground(oldColor);
	     }
	     
	     int progressWidth = (int) (((width  - 4) * value) / (maximum - minimum));
	     rectangle = new Rectangle(2, 2, progressWidth, height - 4);
	     
	     oldColor = gc.getBackground();
	     gc.setBackground(getForeground());
	     gc.fillRectangle(rectangle);
	     gc.setBackground(oldColor);
	}

	public Point computeSize(int wHint, int hHint, boolean changed) {		
	    
		Point size = getSize();
		
		int width = Math.max(40 + 2, size.x);
		int height = Math.max(9 + 2, size.y);
	     
	     if (wHint != SWT.DEFAULT) width = wHint;
	     if (hHint != SWT.DEFAULT) height = hHint;

	     return new Point(width, height);     
	}
	
	public int getValue() {
		return value;
	}

	public int getMinimum() {
		return minimum;
	}

	public void setMinimum(int minimum) {
		this.minimum = minimum;
	}

	public int getMaximum() {
		return maximum;
	}

	public void setMaximum(int maximum) {
		this.maximum = maximum;
	}

	public void setValue(int value) {
		this.value = value;
	}

	public Color getRollover() {
		return rollover;
	}

	public void setRollover(Color rollover) {
		this.rollover = rollover;
	}
}
